import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { writeFileSync, existsSync, mkdirSync } from 'fs';
import { join } from 'path';
import { UploadFileDto } from './dto/upload-file.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Application } from '../application/entities/application.entity';

@Injectable()
export class UploadService {
  private readonly uploadPath = join(process.cwd(), 'uploads');
  constructor(@InjectRepository(Application) private applicationRepository: Repository<Application>) {
    // 确保上传目录存在
    if (!existsSync(this.uploadPath)) {
      mkdirSync(this.uploadPath, { recursive: true }); // 递归创建目录，确保目录结构存在
    }
  }
  async uploadFile(file: Express.Multer.File, uploadFileDto?: UploadFileDto) {
    // 检查文件是否为空
    if (!file) {
      return new HttpException('文件为空', HttpStatus.BAD_REQUEST);
    }
    // 获取文件扩展名
    const fileExtension =
      file.originalname.lastIndexOf('.') >= 0 ? file.originalname.substring(file.originalname.lastIndexOf('.')) : '';
    // 创建要编码的字符串
    const contentToEncode = `${Date.now()}-${file.originalname.replace(fileExtension, '')}`;
    // 转换为base64并替换不适合文件名的字符
    const base64Name = Buffer.from(contentToEncode)
      .toString('base64')
      .replace(/\+/g, '-') // 将'+'替换为'-'
      .replace(/\//g, '_') // 将'/'替换为'_'
      .replace(/=+$/, ''); // 移除尾部的'='
    // 最终文件名：base64名称 + 文件扩展名
    const fileName = `${base64Name}${fileExtension}`;
    // 文件保存路径
    const filePath = join(this.uploadPath, fileName);

    // 保存文件
    writeFileSync(filePath, file.buffer);

    // 返回文件信息
    const fileInfo = {
      name: file.originalname,
      filename: fileName,
      path: filePath,
      url: `${process.env.UPLOAD_HOST}:${process.env.Port}/uploads/${fileName}`, // 可以通过这个URL访问文件
      size: file.size,
      mimetype: file.mimetype,
      description: uploadFileDto?.description,
      categoryId: uploadFileDto?.categoryId,
    };
    // 如果提供了应用ID，更新应用的image_url字段
    if (uploadFileDto?.applicationId) {
      await this.applicationRepository.update(uploadFileDto.applicationId, { image_url: fileInfo.url });
    }
    return fileInfo;
  }
  async uploadFiles(files: Express.Multer.File[], uploadFileDto?: UploadFileDto) {
    if (!files || files.length === 0) {
      return { message: '没有上传文件' };
    }

    const uploadedFiles = await Promise.all(files.map(file => this.uploadFile(file, uploadFileDto)));
    return {
      message: '文件上传成功',
      files: uploadedFiles,
      description: uploadFileDto?.description,
      categoryId: uploadFileDto?.categoryId,
    };
  }
}
